using Engine;
using GameEntitySystem;
using System.Collections.Generic;
using TemplatesDatabase;

namespace Game
{
    public class SubsystemFurnaceBlockBehavior : SubsystemBlockBehavior
    {
        public SubsystemParticles m_subsystemParticles;

        public Dictionary<Point3, FireParticleSystem> m_particleSystemsByCell = new Dictionary<Point3, FireParticleSystem>();

        public override int[] HandledBlocks => new int[2]
        {
            64,
            65
        };

        public override void OnBlockAdded(int value, int oldValue, int x, int y, int z)
        {
            if (Terrain.ExtractContents(oldValue) != 64 && Terrain.ExtractContents(oldValue) != 65)
            {
                DatabaseObject databaseObject = SubsystemTerrain.Project.GameDatabase.Database.FindDatabaseObject("Furnace", SubsystemTerrain.Project.GameDatabase.EntityTemplateType, throwIfNotFound: true);
                var valuesDictionary = new ValuesDictionary();
                valuesDictionary.PopulateFromDatabaseObject(databaseObject);
                valuesDictionary.GetValue<ValuesDictionary>("BlockEntity").SetValue("Coordinates", new Point3(x, y, z));
                Entity entity = SubsystemTerrain.Project.CreateEntity(valuesDictionary);
                SubsystemTerrain.Project.AddEntity(entity);
            }
            if (Terrain.ExtractContents(value) == 65)
            {
                AddFire(value, x, y, z);
            }
        }

        public override void OnBlockRemoved(int value, int newValue, int x, int y, int z)
        {
            if (Terrain.ExtractContents(newValue) != 64 && Terrain.ExtractContents(newValue) != 65)
            {
                ComponentBlockEntity blockEntity = SubsystemTerrain.Project.FindSubsystem<SubsystemBlockEntities>(throwOnError: true).GetBlockEntity(x, y, z);
                if (blockEntity != null)
                {
                    Vector3 position = new Vector3(x, y, z) + new Vector3(0.5f);
                    foreach (IInventory item in blockEntity.Entity.FindComponents<IInventory>())
                    {
                        item.DropAllItems(position);
                    }
                    SubsystemTerrain.Project.RemoveEntity(blockEntity.Entity, disposeEntity: true);
                }
            }
            if (Terrain.ExtractContents(value) == 65)
            {
                RemoveFire(x, y, z);
            }
        }

        public override void OnBlockGenerated(int value, int x, int y, int z, bool isLoaded)
        {
            if (Terrain.ExtractContents(value) == 65)
            {
                AddFire(value, x, y, z);
            }
        }

        public override void OnChunkDiscarding(TerrainChunk chunk)
        {
            var list = new List<Point3>();
            foreach (Point3 key in m_particleSystemsByCell.Keys)
            {
                if (key.X >= chunk.Origin.X && key.X < chunk.Origin.X + 16 && key.Z >= chunk.Origin.Y && key.Z < chunk.Origin.Y + 16)
                {
                    list.Add(key);
                }
            }
            foreach (Point3 item in list)
            {
                RemoveFire(item.X, item.Y, item.Z);
            }
        }

        public override bool OnInteract(TerrainRaycastResult raycastResult, ComponentMiner componentMiner)
        {
            ComponentBlockEntity blockEntity = SubsystemTerrain.Project.FindSubsystem<SubsystemBlockEntities>(throwOnError: true).GetBlockEntity(raycastResult.CellFace.X, raycastResult.CellFace.Y, raycastResult.CellFace.Z);
            if (blockEntity != null && componentMiner.ComponentPlayer != null)
            {
                ComponentFurnace componentFurnace = blockEntity.Entity.FindComponent<ComponentFurnace>(throwOnError: true);
                componentMiner.ComponentPlayer.ComponentGui.ModalPanelWidget = new FurnaceWidget(componentMiner.Inventory, componentFurnace);
                AudioManager.PlaySound("Audio/UI/ButtonClick", 1f, 0f, 0f);
                return true;
            }
            return false;
        }

        public override void OnNeighborBlockChanged(int x, int y, int z, int neighborX, int neighborY, int neighborZ)
        {
            base.OnNeighborBlockChanged(x, y, z, neighborX, neighborY, neighborZ);
        }

        public override void Load(ValuesDictionary valuesDictionary)
        {
            base.Load(valuesDictionary);
            m_subsystemParticles = Project.FindSubsystem<SubsystemParticles>(throwOnError: true);
        }

        public void AddFire(int value, int x, int y, int z)
        {
            var v = new Vector3(0.5f, 0.2f, 0.5f);
            float size = 0.15f;
            var fireParticleSystem = new FireParticleSystem(new Vector3(x, y, z) + v, size, 16f);
            m_subsystemParticles.AddParticleSystem(fireParticleSystem);
            m_particleSystemsByCell[new Point3(x, y, z)] = fireParticleSystem;
        }

        public void RemoveFire(int x, int y, int z)
        {
            var key = new Point3(x, y, z);
            FireParticleSystem particleSystem = m_particleSystemsByCell[key];
            m_subsystemParticles.RemoveParticleSystem(particleSystem);
            m_particleSystemsByCell.Remove(key);
        }
    }
}
